﻿#pragma once
#include <PluginsAction.h>
#include <QObject>
#include "../Frameworks/EquipmentAction.h"

class AbstruactEventMediator;
class Plugin;
class QQmlContext;

class PluginsManager: public QObject, public EquipmentAction, public PluginAction
{
	Q_OBJECT
	using callback_type = std::function<void(QJsonObject const&)>;
	using callback_map_type = std::map<QStringView, callback_type>;
	using callback_multimap_type = std::multimap<QStringView, callback_type>;
public:
	inline static QStringView Identity = u"PluginsManager";
	PluginsManager(QQmlContext* context, QObject* parent = nullptr);
	~PluginsManager();
	void update(QJsonObject const& msg) override;
	void send(QJsonObject const& msg) override;
	void send(QJsonObject const& msg, QStringView to) override;
	void setMediator(AbstruactEventMediator* mediator) override;
	QStringView identity() const override;
	void load(QJsonArray const& arr) override;
	void operate(QVariant v) override;
signals:
	void loadFinished();
	void errors(QString const& text);
private:
	void updateRegister(QJsonObject const& msgObj);
	inline void loadAsync(QStringView group, QStringView name, QStringView cfgFile, Plugin * const p);
	inline void loadSync(QStringView propertyName, QStringView name, QStringView cfgFile, Plugin* const p);
public slots:
	void logsHandle(QString const& logs, int lev);
private slots:
	void plugsErrorHandle(QStringView, QStringView);
	void pluginsLoadFinished(QStringView name);
private:
	bool m_isIntegrity = false;
	QStringList const m_ownTopics;						//拥有的主题
	QStringList const m_needCommands;					//需要的命令字
	std::map<QString, QThread*> m_asyncThreads;			//插件线程存储器
	std::map<QString, Plugin*> m_pluginsMap;			//名称->插件
	std::multimap<QString, Plugin*> m_topic2Plugins;	//主题->插件
	std::multimap<QString, Plugin*> m_command2Plugins;	//命令字->插件
	callback_map_type m_processMsgMap;					//中介者回调集合
	callback_multimap_type m_commandMsgMap;				//命令字处理集合
	AbstruactEventMediator* m_mediator = nullptr;
	QList<QString> m_loadFinishedList;
};
